package com.daxue.configtest.base;

import com.daxue.configtest.exception.impl.BadArgumentException;
import com.daxue.configtest.exception.impl.ConflictException;
import com.daxue.configtest.exception.impl.NotFoundException;
import lombok.experimental.UtilityClass;
import org.jooq.Field;
import org.jooq.SortField;
import org.jooq.UpdatableRecord;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.sql.Timestamp;
import java.util.Optional;

import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.SQLDataType.TIMESTAMP;
import static org.jooq.impl.SQLDataType.VARCHAR;

/**
 * @author daxue0929
 * @date 2023/3/14
 */

public interface DAO<R extends UpdatableRecord<R>, E extends BaseEntity> extends Repository<E> {

    E create(E entity) throws ConflictException, BadArgumentException;

    E create(String id, E entity) throws BadArgumentException, ConflictException;

    Optional<E> find(final String id) throws ConflictException;

    E read(final String id) throws NotFoundException, ConflictException;

    Optional<E> findOne(Sort sort, QueryConditions condition) throws ConflictException;

    Optional<E> findOne(QueryConditions conditions) throws ConflictException;

    E readOne(Sort sort, QueryConditions condition) throws NotFoundException, ConflictException;

    E readOne(QueryConditions conditions) throws NotFoundException, ConflictException;

    Page<E> readAll(Pageable pageable, QueryConditions condition) throws ConflictException;

    E update(String id, E entity) throws NotFoundException, BadArgumentException, ConflictException;

    E delete(String id) throws NotFoundException, ConflictException;

    Page<E> deleteAll(QueryConditions conditions) throws ConflictException;

    @UtilityClass
    class Fields {

        public static final String ID = "id";
        public static final Field<String> ID_FIELD = field(name(ID), VARCHAR);

        public static final String CREATED_ON = "createdOn";
        public static final Field<Timestamp> CREATED_ON_FIELD = field(name(CREATED_ON), TIMESTAMP);

        public static final String MODIFIED_ON = "modifiedOn";
        public static final Field<Timestamp> MODIFIED_ON_FIELD = field(name(MODIFIED_ON), TIMESTAMP);

        public static final SortField<Timestamp> DEFAULT_SORT_FIELD = MODIFIED_ON_FIELD.desc();

    }
}
